package org.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.itextpdf.text.log.LoggerFactory;
import feign.Logger;
import lombok.extern.slf4j.Slf4j;
import org.example.entity.PayLog;
import org.example.entity.PayPlan;
import org.example.entity.PayReconciliation;
import org.example.mapper.PayLogMapper;
import org.example.mapper.PayPlanMapper;
import org.example.mapper.PayReconciliationMapper;
import org.example.service.IPayPlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhaowenting
 * @since 2024-04-02
 */
@Slf4j
@Service
public class PayPlanServiceImpl extends ServiceImpl<PayPlanMapper, PayPlan> implements IPayPlanService {
    @Autowired
    PayLogMapper payLogMapper;
    @Autowired
    PayReconciliationMapper payReconciliationMapper;
    @Override
    public List<PayPlan> orderList() {
        return baseMapper.orderList();
    }
//支付回调

    /**
     * 们通过在 PayPlan 实体类中添加版本号字段，
     * 并在更新数据时比对版本号来实现乐观锁。
     * 如果版本号不一致，表示数据已被其他线程修改，
     * 可以根据实际情况进行相应的处理。
     * @param outTradeNo
     * @param tradeNo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doOrder(String outTradeNo, String tradeNo) {

        //根据传过来的订单号去查询业务系统中对应订单号的业务记录
        LambdaQueryWrapper<PayPlan> payPlanLambdaQueryWrapper = new LambdaQueryWrapper<>();
        payPlanLambdaQueryWrapper.eq(PayPlan::getOutTradeNo, outTradeNo);
        PayPlan payPlan = this.getOne(payPlanLambdaQueryWrapper);

        if (payPlan != null) {
            //将状态改为2是支付成功
            payPlan.setState(2);
            payPlan.setCreateTime(new Date());

            //使用乐观锁更新数据
            boolean updateSuccess = this.updateById(payPlan);
            if (updateSuccess) {
                //去根据订单号去支付记录表查询是否存在这条数据
                //如果不存在就添加记录到支付记录表
                LambdaQueryWrapper<PayLog> payLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
                payLogLambdaQueryWrapper.eq(PayLog::getOutTradeNo, outTradeNo);
                PayLog payLog = payLogMapper.selectOne(payLogLambdaQueryWrapper);
                log.info("===支付成功==");
                if (payLog == null) {
                    payLog = new PayLog();
                    payLog.setPrice(payPlan.getPrice());
                    payLog.setCreateTime(payPlan.getCreateTime());
                    payLog.setOutTradeNo(outTradeNo);
                    payLog.setState(payPlan.getState());
                    payLogMapper.insert(payLog);
                }
                //对账处理
                reconcile(payPlan, payLog);
            } else {
                //处理版本号不一致的情况，例如抛出异常或进行重试操作
                //这里简单示例为抛出异常
                throw new RuntimeException("更新失败，数据已被其他线程修改");
            }
        }
    }

    @Override
    public List<PayPlan> orderListByUserId(Integer userId) {
        return baseMapper.orderListByUserId(userId);
    }

    private void reconcile(PayPlan payPlan, PayLog payLog) {
        // 对账处理逻辑，比较支付计划和支付记录是否匹配，进行相应的处理
        if (payPlan.getPrice().equals(payLog.getPrice())) {
            // 金额匹配，对账成功
            log.info("对账成功，金额匹配");
            PayReconciliation payReconciliation = BeanUtil.copyProperties(payPlan, PayReconciliation.class);
            payReconciliationMapper.insert(payReconciliation);
        } else {
            // 金额不匹配，对账失败
            log.error("对账失败，金额不匹配");
            PayReconciliation payReconciliation = BeanUtil.copyProperties(payPlan, PayReconciliation.class);
            payReconciliationMapper.insert(payReconciliation);
        }
    }

}
